package vampirism.core.shared;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryonet.EndPoint;

// This class is a convenient place to keep things common to both the client and server.
public class Network {
	
	//Port used to connect
	static public final int port = 54555;
	
	//Seed used by all random generators (server,client)
	static public int seed = 8;
	
	//Waiting period in miliseconds before alphaVampire is chosen 
	static public final int startWaitingPeriod = 6000;
	
	//Waiting period in miliseconds before result panel is closed
	static public final int resultWaitingPeriod = 4000;
	
	static public final int biomeCount = 14;
	
	static public final int MAP_W = 256;
	static public final int MAP_H = 256;

	static public final int halfMapWidth = (MAP_W * 8) / 2;
	static public final int halfMapHeight = (MAP_H * 8) / 2;
	
	static public final Random rand = new Random(seed);

	// This registers objects that are going to be sent over the network.
	static public void register(EndPoint endPoint) {
		Kryo kryo = endPoint.getKryo();

		kryo.register(Login.class);
		kryo.register(LoginResult.class);
		kryo.register(LoginResultType.class);

		kryo.register(CreatePlayer.class);
		kryo.register(CreatePlayerResult.class);
		kryo.register(CreatePlayerResultType.class);

		kryo.register(SelectPlayer.class);
		kryo.register(SelectPlayerResult.class);
		kryo.register(SelectPlayerResultType.class);

		kryo.register(LaunchGame.class);
		kryo.register(AddPlayer.class);
		kryo.register(RemoveBody.class);
		kryo.register(GainExp.class);
		
		kryo.register(Move.class);
		kryo.register(UpdatePlayer.class);
		
		kryo.register(Shoot.class);
		kryo.register(AddBullet.class);
		kryo.register(Hit.class);
		
		kryo.register(Account.class);
		kryo.register(Body.class);
		kryo.register(Player.class);
		
		kryo.register(Bullet.class);
		
		
		kryo.register(Rectangle.class);
		kryo.register(Index.class);
		kryo.register(List.class);
		kryo.register(Long.class);
		kryo.register(ArrayList.class);
		
		kryo.register(boolean[].class);
		kryo.register(short[].class);

	}

	static public enum LoginResultType {
		INCORRECT_PASS, ACCOUNT_ALREADY_LOGGED_ON, REG_SUCCESS, LOGIN_SUCCESS, INVALID_EMAIL, INVALID_PASS
	}

	static public enum CreatePlayerResultType {
		NAME_ALREADY_EXISTS, ACCOUNT_ALREADY_LOGGED_ON, INVALID_TYPE, INVALID_NAME, TOO_MANY_CHARACTERS, SUCCESS
	}

	static public enum SelectPlayerResultType {
		INVALID_ID, SUCCESS
	}

	// Client to Server
	// Is sent after pressing 'Confirm' button in login menu
	static public class Login {
		public String email;
		public String pass;
	}

	// Client to Server
	// Is sent after pressing 'Create' button in create menu
	static public class CreatePlayer {
		public String name;
		public byte type;
	}

	// Client to Server
	// Is sent after pressing 'Play' button in select menu
	static public class SelectPlayer {
		public int accountPlayerNum;
	}

	// Client to Server
	// TODO server-side validate
	static public class Move {
		//4 possible input keys from the client (A,S,D,W)
		public boolean[] moving;	
		public float syncX; 
		public float syncY;
	}
	
	// Client to Server
	static public class Shoot {
		public float rotation;
	}

	// Server to Client
	static public class AddBullet {
		public Bullet bullet;
	}
	
	// Server to Client
	//Launch the game after 60 seconds - alphaVampire is chosen and shooting/movement is enabled
	static public class LaunchGame {
		public short alphaId;
	}
	
	// Server to Client
	static public class Hit {
		public short sourceId;
		public short targetId;
		public short damage;
	}
	
	//Server to Client
	static public class GainExp {
		public short bodyIndex;
		public short amount;
	}
	
	// Server to Client
	static public class UpdatePlayer {
		
		public short index;//player index
		public boolean[] moving;//boolean for each of the 4 directions that the player can move to
		public float syncX,syncY;
	}
	
	// Server to Client
	// Is sent back after checking 'Login' packet data
	static public class LoginResult {
		public LoginResultType result;
		public List<Player> myPlayers;
	}
	
	// Server to Client
	// Is sent back after checking 'CreatePlayer' packet data
	static public class CreatePlayerResult {
		public CreatePlayerResultType result;
		public List<Player> myPlayers;
	}
	
	// Server to Client
	// Is sent back after checking 'SelectPlayer' packet data
	static public class SelectPlayerResult {
		public SelectPlayerResultType result;
		public List<Player> allPlayers;
		public boolean gameLaunched;
		public int myPlayerIndex;
	}
	
	// Server to Client
	// Is sent back if someone joined the game
	static public class AddPlayer {
		public Player newPlayer;
	}
	
	// Server to Client
	// Is sent back if someone disconnected or player died
	static public class RemoveBody {
		public short bodyIndex;
	}

}